package com.example.zluserservice.framework.intercept;

import cn.hutool.core.util.ObjectUtil;
import com.example.zluserservice.common.constant.CommonConstant;
import com.example.zluserservice.common.constant.UserCacheConstant;
import com.example.zluserservice.common.util.JwtUtil;
import com.example.zluserservice.common.util.UserThreadLocal;
import com.example.zluserservice.framework.properties.JwtTokenManagerProperties;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @Author zhenliu（孙凌岳）
 * @Description 认证-将User信息存到ThreadLocal的拦截器
 * @Date 2025/6/16 7:58
 * @Version 1.0
 */
@Component
@Slf4j
public class UserTokenInterceptor implements HandlerInterceptor {
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private JwtTokenManagerProperties jwtTokenManagerProperties;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //只对控制器方法（@RequestMapping、@GetMapping……方法）进行拦截
        if(!(handler instanceof HandlerMethod)){
            return true;
        }
        //从header中获取token
        String userToken = request.getHeader(CommonConstant.USER_TOKEN);
        if(!ObjectUtil.isEmpty(userToken)){
            String jwtTokenKey = UserCacheConstant.JWT_TOKEN + userToken;
            String jwtJsonStr = stringRedisTemplate.opsForValue().get(jwtTokenKey);
            if(!ObjectUtil.isEmpty(jwtJsonStr)){
                log.info(jwtTokenManagerProperties.getBase64EncodedSecretKey());
                Claims claims = JwtUtil.parseJWT(jwtTokenManagerProperties.getBase64EncodedSecretKey(), jwtJsonStr);
                String currentUserStr = String.valueOf(claims.get(CommonConstant.CURRENT_USER));
                //存入ThreadLocal
                UserThreadLocal.setSubject(currentUserStr);
            }
        }

        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        UserThreadLocal.remove();
    }
}
